import { message } from 'antd';
import {
  repetition,
  uploadFilePart,
  merge,
  fetchPercentByMd5,
  deleteFile,
  breakFile,
  getUploadFile,
  uploadinstallpackage,
} from '../services/shard';

export default {
  namespace: 'shard',
  state: {
    uploadingFiles: [],
  },

  effects: {
    *repetition({ callback, payload }, { call, put, select }) {
      const { statusCode, data } = yield call(repetition, payload);
      if (statusCode === '0') {
        const uploadingFiles = yield select(_ => _.shard.uploadingFiles);
        const index = uploadingFiles.findIndex(value => value.fileMd5 === data.fileMd5);
        if (index !== -1) {
          uploadingFiles.splice(index, 1);
        }
        const initFile = {
          fileMd5: data.fileMd5,
          fileName: data.fileName,
          total: data.total,
          percent: data.percent,
          needUpload: data.chunks.length,
          status: data.finish ? 2 : 0,
        };
        yield put({
          type: 'save',
          payload: { uploadingFiles: [initFile, ...uploadingFiles] },
        });
        callback(data);
      } else {
        callback({ err: true, fileMd5: payload?.file?.fileMd5 });
      }
    },
    *uploadFilePart({ callback, payload }, { call, put, select }) {
      const response = yield call(uploadFilePart, payload);
      if (response.code === '0') {
        const uploadingFiles = yield select(_ => _.shard.uploadingFiles);
        const index = uploadingFiles.findIndex(value => value.fileMd5 === payload.get('fileMd5'));
        if (index !== -1) {
          const file = uploadingFiles[index];
          const { total, needUpload } = file;
          const percent = Number((((total + 1 - needUpload) * 100) / total).toFixed(2));
          uploadingFiles.splice(index, 1, {
            ...file,
            ...{ percent, needUpload: needUpload - 1, status: percent === 100 ? 1 : 0 },
          });
          yield put({
            type: 'save',
            payload: { uploadingFiles },
          });
          //   if (percent === 100) {
          //     callback();
          //   }
          callback && callback({ percent });
        }
      } else {
        // 上传失败
        yield put({
          type: 'stopUpload',
          payload: payload.get('fileMd5'),
        });
        callback && callback({ err: true, fileMd5: payload.get('fileMd5') });
      }
    },
    *fetchPercent({ callback, payload }, { select, call, put }) {
      const { uploadingFiles } = yield select(state => state.shard);
      if (Object.keys(uploadingFiles).includes(payload.fileMd5)) {
      } else {
        const response = yield call(fetchPercentByMd5, payload);
        if (response.statusCode === '0') {
          yield put({
            type: 'updateFiles',
            payload: response.data,
          });
          callback(response.data);
        }
      }
    },
    *breakFile({ payload }, { call }) {
      yield call(breakFile, payload);
    },
    *uploadinstallpackage({ payload }, { call }) {
      yield call(uploadinstallpackage, payload);
    },
    *deleteFile({ payload }, { call, put, select }) {
      const response = yield call(deleteFile, payload);
      if (response.statusCode === '0') {
        const uploadingFiles = yield select(_ => _.shard.uploadingFiles);
        const index = uploadingFiles.findIndex(value => value.fileMd5 === payload);
        if (index !== -1) {
          uploadingFiles.splice(index, 1);
          yield put({
            type: 'save',
            payload: { uploadingFiles },
          });
        }
      }
    },
    *merge({ payload, callback }, { call, put, select }) {
      const response = yield call(merge, payload);
      if (response.code === '0') {
        message.success('上传成功');
        const uploadingFiles = yield select(_ => _.shard.uploadingFiles);
        const index = uploadingFiles.findIndex(value => value.fileMd5 === payload.fileMd5);
        if (index !== -1) {
          callback && callback();
          const file = uploadingFiles[index];
          uploadingFiles.splice(index, 1, { ...file, ...{ status: 2 } });
          yield put({
            type: 'save',
            payload: { uploadingFiles },
          });
        }
      } else {
        // 上传失败
        yield put({
          type: 'stopUpload',
          payload: payload.fileMd5,
        });
        callback && callback({ err: true, fileMd5: payload.fileMd5 });
      }
    },
    *getUploadFile({ payload, callback }, { call, put }) {
      const response = yield call(getUploadFile, payload);
      yield put({
        type: 'save',
        payload: { response },
      });
      if (callback) callback(response);
    },
  },
  reducers: {
    updateFiles(state, action) {
      const { uploadingFiles } = state;
      const files = { uploadingFiles: [...action.payload, ...uploadingFiles] };
      return {
        ...state,
        ...files,
      };
    },
    stopUpload(state, action) {
      const { uploadingFiles } = state;
      if (uploadingFiles[action.payload]) {
        uploadingFiles[action.payload].status = '2';
      }
      return state;
    },
    save(state, action) {
      return {
        ...state,
        ...action.payload,
      };
    },
  },
};
